package com.kinyx.framework.db.sentence.res;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.metamodel.SingularAttribute;

import com.kinyx.framework.annotation.assist.Tester;
import com.kinyx.framework.bean.StringFormatter;
import com.kinyx.framework.db.configs.DBConfigs;
import com.kinyx.framework.db.sentence.defines.InsertResSentence;
import com.kinyx.framework.utils.KListUtils;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;

/**
 * 新增语句
 */
@Tester("com.kinyx.framework.db.sentence.res.demo.insert.INSERT_Tester")
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class KINSERT extends _Sentence_CRUD implements InsertResSentence {

	/** 表子句 */
	private final Table table;

	// ================================================================= values ================================================================= //

	/** 列子句列表 */
	private final List<ParamColumn> columns = new ArrayList<>();

	/**
	 * 新增VALUES子句
	 * @param column 列
	 * @param param 参数
	 * @return 本对象
	 */
	public KINSERT values(final Column column, final Object param) {
		this.columns.add(new ParamColumn(column, param));
		return this;
	}
	/**
	 * 新增VALUES子句
	 * @param attr 属性
	 * @param param 参数
	 * @return 本对象
	 */
	public KINSERT values(final SingularAttribute<?, ?> attr, final Object param) {
		return this.values(Res.toCol(attr), param);
	}

	// ================================================================= 实现方法 ================================================================= //
	@Override
	public String getSentence(final DBConfigs configs, final boolean isSQL, final boolean withTableAlias) {
		return StringFormatter.of()//
				.x("INSERT INTO %s", this.table.getSentence(configs, isSQL, withTableAlias))//
				.x(" (%s)", () -> {
					if (KINSERT.this.columns.isEmpty()) { return StringFormatter.Type.Ignore; }
					return KListUtils.join(this.columns, ", ", (column, index) -> { return column.getSentence(configs, isSQL, withTableAlias); });
				})//
				.x(" VALUES (%s)", () -> {
					if (KINSERT.this.columns.isEmpty()) { return StringFormatter.Type.Ignore; }
					return KListUtils.join(this.columns, ", ", (column, index) -> { return "?"; });
				})//
				.format();
	}

	@Override
	public List<Object> getParams() {
		final List<Object> params = new ArrayList<>();
		// columns params
		this.columns.forEach(column -> params.add(column.getParam()));
		return params;
	}

}
